
// NOTE: the following arrays are GLOBAL (used in processOSC and processSerial, as well as in interpretCommand function):
 // max of two addresses (top and sub), of a max length of 24 characters:
char address[2][24];
//long auxdata[2]; // to store a max of two arguments (note: we will only use LONGs)
int data[2]; // this is to have -1 as NO DATA, to detect errors. 

//interpretCommand(const char& address[2][], const int& data[2]) { 
  
void interpretCommand() {
  
  // First, commands not addressing the configuration of spots, but some low level things (for making measures, etc):
    if ( !strcmp(address[0], "takeSnapshot" ) ) { // will reset all the spots, but the 0, and use it for taking measures:
      IO.scanArea_OSC(); // Will scan once, and send data. 
      // NOTE: this is NOT very nice... in fact, it wold be better if the scanning area mode where a method of living spot (or in the future, of laserSensingDisplay object)
    } 
   
  
  // First, global commands (for all spots):1
  if ( !strcmp(address[0], "resetAll" ) ) { 
         spotConfig.allSpotsInit();   
    } 
    
   // ============================== SPECIAL MODES ========================================
   else if ( !strcmp(address[0], "standBy" ) ) { // will put ALL the spots in stand by mode
      spotConfig.allStandBy();
    } 
    else if ( !strcmp(address[0], "measureMode" ) ) { // will reset all the spots, but the 0, and use it for taking measures:
      spotConfig.measureMode();
    } 
  
   // ============================== PRE-DEFINED DEMO MODES ===============================
   else if ( !strcmp(address[0], "oneContourFollowing" ) ) { 
      spotConfig.oneContourFollowing();
      spotConfig.resetTimer();  
    } 
   else if ( !strcmp(address[0], "twoContourFollowing" ) ) { 
      spotConfig.twoContourFollowing();
      spotConfig.resetTimer();  
    }
   else if ( !strcmp(address[0], "oneSimpleBouncing" ) ) { 
      spotConfig.oneSimpleBouncing();
      spotConfig.resetTimer();  
    }
    else if ( !strcmp(address[0], "twoSimpleBouncing" ) ) { 
      spotConfig.twoSimpleBouncing();
      spotConfig.resetTimer();  
    }
    else if ( !strcmp(address[0], "oneSnellLaw" ) ) { 
      spotConfig.oneSnellLaw();
      spotConfig.resetTimer();  
    }
    
      else if ( !strcmp(address[0], "threeNewtonianBouncing" ) ) { 
      spotConfig.newtonianBouncingOnly(3);
      spotConfig.resetTimer();  
    } 
    
     else if ( !strcmp(address[0], "setAllThresholdMode" ) ) { // this takes one argument
       int value=data[0];
       if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
       for(int i=0; i<spotConfig.numSpots; i++) {
         if (value==0) spotConfig.spotArray[i].setAutoThreshold(false); else spotConfig.spotArray[i].setAutoThreshold(true);
    }
       }
   }
    
    // ============================== GLOBAL SENDING HARDWARE SELECT ===============================
    else if ( !strcmp(address[0], "setGreenLaser" ) ) { 
       int value=data[0];
       if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
        if (value==0) IO.setGreenPower(LOW); else IO.setGreenPower(HIGH); 
       }
    } 
    
     else if (!strcmp( address[0], "stopAllSending" ) ) { // note: this stops both global and per-spot sending
      int value=data[0];
       if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
         if (value==0) spotConfig.stopAllSending();
       }
    }
    else if (!strcmp( address[0], "sendAllOSC" ) ){
      int value=data[0];
      if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
       if (value==0) spotConfig.sendAllOSC=false ; else spotConfig.sendAllOSC=true;
      }
    }
     else if (!strcmp( address[0], "sendAllSerial" ) ){ 
      int value=data[0];
      if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
       if (value==0) spotConfig.sendAllSerial=false ; else spotConfig.sendAllSerial=true;
      }
    } 
   else if (!strcmp( address[0], "sendAllMIDI" ) ){ 
      int value=data[0];
      if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
       if (value==0) spotConfig.sendAllMIDI=false ; else spotConfig.sendAllMIDI=true;
      }
    } 
    // ============================== GLOBAL DATA TO BE SENT (through any hardware) =================
    else if( !strcmp( address[0] , "sendAllPosition" ) ) { 
       int value=data[0];
        if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
         if (value==0) spotConfig.sendingAllPosition=false; else spotConfig.sendingAllPosition=true;   
        //pinMode(31, OUTPUT); if (data==0) digitalWrite(31,LOW); else digitalWrite(31, HIGH);    
      }        
     }
    else if( !strcmp( address[0] , "sendAllColor" ) ) { 
       int value=data[0];
      if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
       if (value==0) spotConfig.sendingAllColor=false; else spotConfig.sendingAllColor=true;   
        //pinMode(31, OUTPUT); if (data==0) digitalWrite(31,LOW); else digitalWrite(31, HIGH);  
      }        
     }
    else if( !strcmp( address[0] , "sendAllCollision" ) ) { 
        int value=data[0];
      if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
       if (value==0) spotConfig.sendingAllCollision=false; else spotConfig.sendingAllCollision=true;   
        //pinMode(31, OUTPUT); if (data==0) digitalWrite(31,LOW); else digitalWrite(31, HIGH);      
      }        
     }
    else if( !strcmp( address[0] , "sendAllWall" ) ) { 
        int value=data[0];
      if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
       if (value==0) spotConfig.sendingAllTouchWall=false; else spotConfig.sendingAllTouchWall=true;   
        //pinMode(31, OUTPUT); if (data==0) digitalWrite(31,LOW); else digitalWrite(31, HIGH);     
      }        
     }
     else if( !strcmp( address[0] , "sendAllAngle" ) ) { 
       int value=data[0];
      if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
       if (value==0) spotConfig.sendingAllAngle=false; else spotConfig.sendingAllAngle=true;   
        //pinMode(31, OUTPUT); if (data==0) digitalWrite(31,LOW); else digitalWrite(31, HIGH); 
      }        
     }
    // End of commands for ALL spots
    else {
   // ============================== PER-SPOT ADDRESSING ===============================================
   // Note: toplevel address matching means the spot identifier
   for (int i=0; i<spotConfig.numSpots; i++) {
          if( !strcmp(address[0],  spotConfig.spotArray[i].spotName) ){ // in this case, we are refering to spot i 
               // Serial.print("Spot Addressed: "); Serial.println(address[0]); 
               //Second level address matching for indicating which parameter to modify. We need to do this with a lot of "ifs":           
                
                // (a)  ------------------- Selection of the sending channel (serial, OSC or Midi), not exclusive  -------------------  
                // Note: check reception error? (e.g., no address[1])
                if (!strcmp( address[1], "stopAllSending" ) ) { // note: this per-spot sending (on ANY channel)
                    int value=data[0];
                    if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
                      if (value==0) spotConfig.spotArray[i].stopAllSending();
                    }
                }
                else if( !strcmp( address[1] , "sendSerial" ) ) { 
                     // Check if it has to start or stop sending data on serial port: 
                    int value=data[0];
                    if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
                     if (value==0) spotConfig.spotArray[i].sendSerial=false; else spotConfig.spotArray[i].sendSerial=true;
                    }
                }
                else if( !strcmp( address[1] , "sendOSC" ) ) { 
                     //Serial.print("Command: "); Serial.print(address[1]); Serial.print(", Argument: "); Serial.println(recMes.getArgInt(0)); 
                     // Check if it has to start or stop sending OSC data over Ethernet: 
                     int value=data[0];
                      if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
                       if (value==0) spotConfig.spotArray[i].sendOSC=false; else spotConfig.spotArray[i].sendOSC=true;  
                    // for tests:
                     //pinMode(30, OUTPUT); if (data==0) digitalWrite(30,LOW); else digitalWrite(30, HIGH); 
                      }                
                }
                 else if( !strcmp( address[1] , "sendMIDI" ) ) { 
                     // Check if it has to start or stop sending Midi data: 
                   int value=data[0];
                    if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
                      if (value==0) spotConfig.spotArray[i].sendMIDI=false; else spotConfig.spotArray[i].sendMIDI=true;       
                  }           
                }
                
                // (b) ------------------- Selection of the sending data (through any available channel)  ------------------- 
                else if( !strcmp( address[1] , "sendingPosition" ) ) { 
                    int value=data[0];
                    if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
                      if (value==0) spotConfig.spotArray[i].sendingPosition=false; else spotConfig.spotArray[i].sendingPosition=true;   
                     //pinMode(31, OUTPUT); if (data==0) digitalWrite(31,LOW); else digitalWrite(31, HIGH);   
                    }                   
                }
                else if( !strcmp( address[1], "sendingAngle" ) ) { 
                       int value=data[0];
                    if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
                      if (value==0) spotConfig.spotArray[i].sendingAngle=false; else spotConfig.spotArray[i].sendingAngle=true;
                  }
                }
                 else if( !strcmp( address[1], "sendingColor" ) ) { 
                       int value=data[0];
                      if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
                        if (value==0) spotConfig.spotArray[i].sendingColor=false; else spotConfig.spotArray[i].sendingColor=true;
                  }
                }
                  else if( !strcmp( address[1], "sendingBump" ) ) { 
                       int value=data[0];
                      if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
                        if (value==0) spotConfig.spotArray[i].sendingCollision=false; else spotConfig.spotArray[i].sendingCollision=true;
                  }
                }
                 else if( !strcmp( address[1], "sendingBorder" ) ) { 
                       int value=data[0];
                      if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
                        if (value==0) spotConfig.spotArray[i].sendingTouchWall=false; else spotConfig.spotArray[i].sendingTouchWall=true;
                  }
                }
              
                // (c) And finally, other parameters not related to sound: 
                else if( !strcmp( address[1] , "kill" ) ) spotConfig.spotArray[i].alive = false;
                else if( !strcmp( address[1] , "resucite" ) ) spotConfig.spotArray[i].alive = true;
                        
                // BEHAVIOUR: 
                // ****** NOTE: better in the future to call a setting function with more default parameters... 
                else if( !strcmp( address[1] , "contourFollowing" ) ) spotConfig.spotArray[i].behaviourMode = COUNTOUR_FOLLOWING; 
                else if( !strcmp( address[1] , "newtonDynamics" ) ) spotConfig.spotArray[i].behaviourMode =  NEWTON_DYNAMICS; 
                else if( !strcmp( address[1] , "simpleBouncing" ) ) spotConfig.spotArray[i].behaviourMode = SIMPLE_BOUNCING; 
                else if( !strcmp( address[1] , "snellLaw" ) ) spotConfig.spotArray[i].behaviourMode = SNELL_LAW; 
                else if( !strcmp( address[1] , "standBy" ) ) spotConfig.spotArray[i].behaviourMode = STAND_BY; 
                
                // Other controls:
               else if ( !strcmp(address[1], "setThresholdMode" ) ) { 
                 int value=data[0];
                   if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
                     if (value==0) spotConfig.spotArray[i].setAutoThreshold(false); else spotConfig.spotArray[i].setAutoThreshold(true);
                  }
                }
                else if( !strcmp( address[1] , "speedUp" ) ) {  
                   spotConfig.spotArray[i].vx*=1.5;
                   spotConfig.spotArray[i].vy*=1.5;   
                   spotConfig.spotArray[i].speedContourFollowing*= 1.1;
                   
                }
                else if( !strcmp( address[1] , "slowDown" ) ) { 
                   spotConfig.spotArray[i].vx/=1.5;
                   spotConfig.spotArray[i].vy/=1.5;    
                   spotConfig.spotArray[i].speedContourFollowing/= 1.1;
                }
                 else if( !strcmp( address[1] , "adjustPlus" ) ) {  // adjust offset angle recentering vector
                   spotConfig.spotArray[i].addErrorAngle(1.0*PI/180); // one degree at a time
                }
                else if( !strcmp( address[1] , "adjustMinus" ) ) {  // adjust offset angle recentering vector
                 spotConfig.spotArray[i].addErrorAngle(-1.0*PI/180);
                }
                else if( !strcmp( address[1] , "setPos" ) ) {  // adjust offset angle recentering vector
                int value1=data[0], value2=data[1]; // positions are in AD mirror values:0 to 4095
                   if ((value1!=-1)&&(value2!=-1)) spotConfig.spotArray[i].moveSpot(value1, value2);//update the position of the spot and move it
                }
                else if( !strcmp( address[1] , "showPushVector" ) ) {  // adjust offset angle recentering vector
                int value=data[0];
                 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
                   if (value==0) spotConfig.spotArray[i].traceNormalVector=false; else spotConfig.spotArray[i].traceNormalVector=true;
                 }
                }
                
                else if( !strcmp( address[1] , "radius" ) ) { 
                    // Get radius value:
                    // ...
                    
                }
       
          }
      }
  }
  }
